package com.ceic.hn.efiletransfer

import org.apache.commons.io.monitor.FileAlterationListenerAdaptor
import org.apache.commons.io.monitor.FileAlterationMonitor
import org.apache.commons.io.monitor.FileAlterationObserver
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.core.task.TaskExecutor
import java.io.File

class EFileTransfer(transferSetting: TransferSetting, private val taskExecutor: TaskExecutor) {

    private val _channel: SSHChannel = SSHChannel.create(transferSetting.channel)
    private val _monitors: List<FileAlterationMonitor> = transferSetting.registry.map {
        val observer = FileAlterationObserver(it.inputPath).apply {
            addListener(TransferListener(it.outputPath, _channel, taskExecutor))
        }
        FileAlterationMonitor(transferSetting.pollInSeconds * 1000L).apply {
            addObserver(observer)
        }
    }


    fun start() {
        _monitors.forEach {
            it.start()
        }
    }

    fun stop() {
        _monitors.forEach {
            it.stop()
        }
        _channel.close()
    }

    class TransferListener(
        private val outputPath: String,
        private val channel: SSHChannel,
        private val taskExecutor: TaskExecutor
    ) : FileAlterationListenerAdaptor() {

        override fun onFileCreate(file: File) {
            taskExecutor.execute {
                logger.info("find file, input file: {}, outputPath: {} ", file.absolutePath, outputPath)
                try {
                    channel.write(file, outputPath)
                    logger.info("transfer file success, input file: {}, outputPath: {} ", file.absolutePath, outputPath)
                } catch (ex: Exception) {
                    logger.error("transfer file failed, input file: {}, outputPath: {}", file.absolutePath, outputPath, ex)
                }
            }
        }
    }

    companion object {
        val logger: Logger = LoggerFactory.getLogger(EFileTransfer::class.java)
    }

}